package com.qingzhuge.web.autoconfigure;

import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.qingzhuge.common.jwt.security.DataSecurityAction;
import com.qingzhuge.common.jwt.security.impl.Base64SecurityAction;
import com.qingzhuge.web.converter.WithSignMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static com.alibaba.fastjson.serializer.SerializerFeature.*;

/**
 * @author : zero.xiao
 * @description : HttpMessageConverter 配置
 * @date :2018/7/4 0004 下午 16:28
 * @modified :
 * @since : 1.0.0
 */
@Configuration
public class FastJsonConfiguration {


    @Bean
    public DataSecurityAction dataSecurityAction() {
        return new Base64SecurityAction();
    }


    /**
     * 集成fastjson
     *
     * @return HttpMessageConverters
     */
    @Bean
    public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        // 1. 需要定义一个converter转换消息的对象
        FastJsonHttpMessageConverter converter = new WithSignMessageConverter();
        // 2. 添加fastjson的配置信息，比如:是否需要格式化返回的json的数据
        // 3. 在converter中添加配置信息
        converter.setFastJsonConfig(fastjsonConfig());
        converter.setSupportedMediaTypes(getSupportedMediaType());
        return converter;
    }

    /**
     * fastjson的配置
     */
    FastJsonConfig fastjsonConfig() {
        //序列化配置
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                PrettyFormat,
                // 输出key时是否使用双引号
                QuoteFieldNames,
                // 是否输出值为null的字段
                //WriteMapNullValue,
                //数值字段如果为null,输出为0,而非null
                //WriteNullNumberAsZero,
                //Collection字段如果为null,输出为[],而非null
                WriteNullListAsEmpty,
                //字符类型字段如果为null,输出为"",而非null
                //WriteNullStringAsEmpty,
                WriteEnumUsingToString,
                //Boolean字段如果为null,输出为false,而非null
                //WriteNullBooleanAsFalse,
                // null String也要输出
                //WriteMapNullValue,
                // Date的日期转换器
                WriteDateUseDateFormat,
                //禁止循环引用
                DisableCircularReferenceDetect
        );
        fastJsonConfig.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        fastJsonConfig.setCharset(StandardCharsets.UTF_8);
        //解决转json精度丢失的问题
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
        serializeConfig.put(BigDecimal.class, ToStringSerializer.instance);
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        serializeConfig.put(Double.class, ToStringSerializer.instance);
        serializeConfig.put(Double.TYPE, ToStringSerializer.instance);
        fastJsonConfig.setSerializeConfig(serializeConfig);
        return fastJsonConfig;
    }

    /**
     * 支持的mediaType类型
     * 处理中文乱码问题
     */
    List<MediaType> getSupportedMediaType() {
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        mediaTypes.add(MediaType.TEXT_PLAIN);
        mediaTypes.add(MediaType.APPLICATION_XML);
        mediaTypes.add(MediaType.TEXT_HTML);
        return mediaTypes;
    }
}